package com.newgrand.utils;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.newgrand.domain.model.I8ReturnModel;
import com.newgrand.utils.filter.MyX509TrustManager;
import com.newgrand.utils.filter.NullHostNameVerifier;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Map;

public class HttpClientUtil {

    public static I8ReturnModel<String> sendPost(String postUrl, String body) {
        return sendPost(postUrl, null, body, "POST`");
    }

    public static I8ReturnModel<String> sendPost(String postUrl, Map<String, String> headers, String body, String method) {
        StringBuilder result = new StringBuilder();
        HttpsURLConnection connection = null;
        try {
            //信任所有SSL证书
            HttpsURLConnection.setDefaultHostnameVerifier(new NullHostNameVerifier());
            SSLContext sslContext = SSLContext.getInstance("TLS");
            TrustManager[] tm = {new MyX509TrustManager()};
            sslContext.init(null, tm, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();


            /* 1. 获取访问地址URL */
            URL url = new URL(postUrl);

            /* 2. 创建HttpURLConnection对象 */
            connection = (HttpsURLConnection) url.openConnection();

            connection.setSSLSocketFactory(ssf);
            /* 3. 设置请求参数（过期时间，输入、输出流、访问方式），以流的形式进行连接 */
            // 设置请求方式
            if (StringUtils.isEmpty(method)) {
                method = "POST";
            }
            connection.setRequestMethod(method);
            // 设置连接超时时间
            connection.setConnectTimeout(20000);
            // 设置读取超时时间
            connection.setReadTimeout(60000);
            // 设置是否向HttpURLConnection输出
            connection.setDoOutput(true);
            // 设置是否使用缓存
            connection.setUseCaches(false);
            // 设置此 HttpURLConnection 实例是否应该自动执行 HTTP 重定向
            connection.setInstanceFollowRedirects(true);
            // 添加 HTTP HEAD 中的一些参数。
            // 设置请求格式
            connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
            // JDK8中，HttpURLConnection默认开启Keep-Alive
            connection.setRequestProperty("Connection", "Keep-Alive");
//            connection.setRequestProperty("Accept-Charset", "UTF-8");
            connection.setRequestProperty("contentType", "UTF-8");

            // 设置请求Headers
            if (!headers.isEmpty()) {
                for (String item : headers.keySet()) {
                    connection.setRequestProperty(item, headers.get(item));
                }
            }

            /* 4. 处理输入输出 */
//            StringBuilder params = new StringBuilder();
//            // 表单参数与get形式一样
////            for (NameValuePair v : formdata) {
////                params.append(v.getName()).append("=").append(URLEncoder.encode(v.getValue(), "utf-8")).append("&");
////            }
//            PrintWriter writer = new PrintWriter(connection.getOutputStream());
//            writer.write(params.toString());
//            writer.flush();
//            writer.close();
            if (!body.isEmpty()) {
                OutputStream out = connection.getOutputStream();
                out.write(body.getBytes(StandardCharsets.UTF_8));
                out.flush();
            }

            InputStream inputStream = connection.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
            String line;
            while ((line = reader.readLine()) != null) {
                result.append(line);
            }
            //根据responseCode来获取输入流，此处错误响应码的响应体内容也要获取（看服务端的返回结果形式决定）
            if (HttpURLConnection.HTTP_OK == connection.getResponseCode()) {
                return I8ReturnModel.success("请求成功", result.toString());
            }
            return I8ReturnModel.errorCode(String.valueOf(connection.getResponseCode()), result.toString());
        } catch (Exception ex) {
//            log.info(postUrl + "，请求异常：" + ex.getMessage());
            return I8ReturnModel.error("请求异常：" + ex.getMessage());
        } finally {
            /* 5. 断开连接 */
            assert connection != null;
            connection.disconnect();
        }
    }
}
